//package com.service.impl;
//
//import com.alibaba.fastjson.JSON;
//import com.alibaba.fastjson.JSONObject;
//import com.dao.YishiDao;
//import com.entity.view.WebsocketView;
//import com.service.YishiService;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import javax.websocket.*;
//import javax.websocket.server.PathParam;
//import javax.websocket.server.ServerEndpoint;
//import java.util.ArrayList;
//import java.util.List;
//import java.util.Map;
//import java.util.Set;
//import java.util.concurrent.ConcurrentHashMap;
//import java.util.concurrent.atomic.AtomicInteger;
//
///**
// * WebSocket的操作类
// */
//@Component
//@Slf4j
///**
// * html页面与之关联的接口
// * var reqUrl = "http://localhost:8081/websocket/" + cid;
// * socket = new WebSocket(reqUrl.replace("http", "ws"));
// */
//@ServerEndpoint("/websocket/{sid}")
//public class WebSocketServer {
//
//    @Autowired
//    private YishiService yishiService;
//
//    /**
//     * 静态变量，用来记录当前在线连接数，线程安全的类。
//     */
//    private static AtomicInteger onlineSessionClientCount = new AtomicInteger(0);
//
//    /**
//     * 存放所有在线的客户端
//     */
//    private static Map<String, Session> onlineSessionClientMap = new ConcurrentHashMap<>();
//
//    /**
//     * 连接sid和连接会话
//     */
//    private String sid;
//    private Session session;
//
//    /**
//     * 连接建立成功调用的方法。由前端<code>new WebSocket</code>触发
//     *
//     * @param sid     每次页面建立连接时传入到服务端的id，比如用户id等。可以自定义。
//     * @param session 与某个客户端的连接会话，需要通过它来给客户端发送消息
//     */
//    @OnOpen
//    public void onOpen(@PathParam("sid") String sid, Session session) {
//        /**
//         * session.getId()：当前session会话会自动生成一个id，从0开始累加的。
//         */
//        log.info("连接建立中 ==> session_id = {}， sid = {}", session.getId(), sid);
//        //加入 Map中。将页面的sid和session绑定或者session.getId()与session
//        //onlineSessionIdClientMap.put(session.getId(), session);
//        onlineSessionClientMap.put(sid, session);
//
//        Set<String> allSids = onlineSessionClientMap.keySet();
//        List<String> usernameList = new ArrayList<>(); // 实例化一个 ArrayList
//
//// 遍历sid值
//        for (String sid1 : allSids) {
//            usernameList.add(sid1); // 向列表中添加元素
//        }
//
//
//        List<WebsocketView> list = yishiService.selectUsernameByTable(usernameList);
//        for (WebsocketView ls :list){
//            ls.getSource_table();
//            ls.getYonghuming();
//        }
//        //在线数加1
//        onlineSessionClientCount.incrementAndGet();
//        this.sid = sid;
//        this.session = session;
//        sendToOne(sid, "连接成功");
//        log.info("连接建立成功，当前在线数为：{} ==> 开始监听新连接：session_id = {}， sid = {},。", onlineSessionClientCount, session.getId(), sid);
//    }
//
//    /**
//     * 连接关闭调用的方法。由前端<code>socket.close()</code>触发
//     *
//     * @param sid
//     * @param session
//     */
//    @OnClose
//    public void onClose(@PathParam("sid") String sid, Session session) {
//        //onlineSessionIdClientMap.remove(session.getId());
//        // 从 Map中移除
//        onlineSessionClientMap.remove(sid);
//
//        //在线数减1
//        onlineSessionClientCount.decrementAndGet();
//        log.info("连接关闭成功，当前在线数为：{} ==> 关闭该连接信息：session_id = {}， sid = {},。", onlineSessionClientCount, session.getId(), sid);
//    }
//
//    /**
//     * 收到客户端消息后调用的方法。由前端<code>socket.send</code>触发
//     * * 当服务端执行toSession.getAsyncRemote().sendText(xxx)后，前端的socket.onmessage得到监听。
//     *
//     * @param message
//     * @param session
//     */
//    @OnMessage
//    public void onMessage(String message, Session session) {
//        /**
//         * html界面传递来得数据格式，可以自定义.
//         * {"sid":"user-1","message":"hello websocket"}
//         */
//        JSONObject jsonObject = JSON.parseObject(message);
//        String toSid = jsonObject.getString("sid");
//        String msg = jsonObject.getString("message");
//        log.info("服务端收到客户端消息 ==> fromSid = {}, toSid = {}, message = {}", sid, toSid, message);
//        // 检查接收消息的人（医生）是否在线
//        Session toSession = onlineSessionClientMap.get(toSid);
//        if (toSession == null){
//            saveOfflineMessage(toSid,msg);
//            log.info("接收者离线，已将消息保存到数据库，sid = {}", toSid);
//            sendlixianOne(sid, toSid+"-接受者离线");
//        }else {
//            // 接收者在线，直接发送消息
//            sendToOne(toSid, msg);
//        }
//
//
//
//
//
//
//
//
////        /**
////         * 模拟约定：如果未指定sid信息，则群发，否则就单独发送
////         */
////        if (toSid == null || toSid == "" || "".equalsIgnoreCase(toSid)) {
////            sendToAll(msg);
////        } else {
////            sendToOne(toSid, msg);
////        }
//    }
//
//
//    private void saveOfflineMessage(String toSid, String message) {
//        // 将消息保存到数据库或任何离线用户的存储机制中
//        // 示例：可以将其保存到具有发送者、接收者、消息、时间戳等列的数据库表中
//        // 您的数据库模型可能是：OfflineMessage(sender, receiver, message, timestamp)
//        // 将此消息保存到表中以备后续检索
//        // offlineMessageRepository.save(new OfflineMessage(sid, toSid, message, LocalDateTime.now()));
//    }
//
//    // 将离线消息发送给医生当其上线时
//    private void sendOfflineMessagesToDoctor(String doctorSid) {
//        // 从数据库中检索医生（接收者）的离线消息
//        // 遍历消息并逐一发送给医生
//        // 使用sendToOne()方法将这些消息发送给医生当其上线时
//    }
//
//
//    /**
//     * 发生错误调用的方法
//     *
//     * @param session
//     * @param error
//     */
//    @OnError
//    public void onError(Session session, Throwable error) {
//        log.error("WebSocket发生错误，错误信息为：" + error.getMessage());
//        error.printStackTrace();
//    }
//
//    /**
//     * 群发消息
//     *
//     * @param message 消息
//     */
//    private void sendToAll(String message) {
//        // 遍历在线map集合
//        onlineSessionClientMap.forEach((onlineSid, toSession) -> {
//            // 排除掉自己
//            if (!sid.equalsIgnoreCase(onlineSid)) {
//                log.info("服务端给客户端群发消息 ==> sid = {}, toSid = {}, message = {}", sid, onlineSid, message);
//                toSession.getAsyncRemote().sendText(message);
//            }
//        });
//    }
//
//    /**
//     * 指定发送消息
//     *
//     * @param toSid
//     * @param message
//     */
//    private void sendToOne(String toSid, String message) {
//        // 通过sid查询map中是否存在
//        Session toSession = onlineSessionClientMap.get(toSid);
//        if (toSession == null) {
//            log.error("服务端给客户端发送消息 ==> toSid = {} 不存在, message = {}", toSid, message);
//            return;
//        }
//        // 异步发送
//        log.info("服务端给客户端发送消息 ==> toSid = {}, message = {}", toSid, message);
//        toSession.getAsyncRemote().sendText(sid+"-"+message);
//        /*
//        // 同步发送
//        try {
//            toSession.getBasicRemote().sendText(message);
//        } catch (IOException e) {
//            log.error("发送消息失败，WebSocket IO异常");
//            e.printStackTrace();
//        }*/
//    }
//
//    /**
//     * 指定发送消息
//     *
//     * @param toSid
//     * @param message
//     */
//    private void sendlixianOne(String toSid, String message) {
//        // 通过sid查询map中是否存在
//        Session toSession = onlineSessionClientMap.get(toSid);
//        if (toSession == null) {
//            log.error("服务端给客户端发送消息 ==> toSid = {} 不存在, message = {}", toSid, message);
//            return;
//        }
//        // 异步发送
//        log.info("服务端给客户端发送消息 ==> toSid = {}, message = {}", toSid, message);
//        toSession.getAsyncRemote().sendText(message);
//        /*
//        // 同步发送
//        try {
//            toSession.getBasicRemote().sendText(message);
//        } catch (IOException e) {
//            log.error("发送消息失败，WebSocket IO异常");
//            e.printStackTrace();
//        }*/
//    }
//
//}
